package com.rit.secs;

import Messages.AlertCanceled;
import Messages.EntrantDetected;
import Messages.InvalidVarListException;
import Messages.Util;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;


public class C2DMReceiver extends BroadcastReceiver{  
	
	// Google Service
	private final String REGISTRATION = "com.google.android.c2dm.intent.REGISTRATION";
	private final String RECEIVE = "com.google.android.c2dm.intent.RECEIVE";
	
	// Registration Extras
	private final String REGISTRATION_ID = "registration_id";
	private final String ERROR = "error";
	private final String UNREGISTERED  = "unregistered";
	
	// Error Codes
	private final String SERVICE_NOT_AVAILABLE = "SERVICE_NOT_AVAILABLE";
	private final String ACCOUNT_MISSING = "ACCOUNT_MISSING";
	private final String AUTHENTICATION_FAILED = "AUTHENTICATION_FAILED";
	private final String TOO_MANY_REGISTRATIONS = "TOO_MANY_REGISTRATIONS";
	private final String INVALID_SENDER = "INVALID_SENDER";
	private final String PHONE_REGISTRATION_ERROR = "PHONE_REGISTRATION_ERROR";
	
	// Exponential backoff time
	private static long backoff = 1000;
	
	@Override
	public void onReceive(Context context, Intent intent) {
		
		System.out.println("C2DMReceiver got message: " + intent.getAction());
		
		if(intent.getAction().equals(REGISTRATION)) {
			System.out.println("C2DMReceiver: Enter REGISTRATION");
			handleRegistration(context, intent);
		}
		else if(intent.getAction().equals(RECEIVE)) {
			System.out.println("C2DMReceiver: Enter RECEIVE"); 
			handleMessage(context, intent);
		}
		else {
			System.out.println("C2DMReceiver: Received other intent... " + intent.getAction());
		}
		
	}
	
	private void handleRegistration(Context context, Intent intent) {
		
		// Retrieve registration ID or null
		String registrationId = intent.getStringExtra(REGISTRATION_ID);
		
		final String regError = intent.getStringExtra(ERROR);
		if(regError != null) {
			
			System.err.println("**** Error: " + intent.getStringExtra(ERROR));
			
			if(regError.equals(SERVICE_NOT_AVAILABLE)) {
				System.out.println("C2DMReceiver: SERVICE_NOT_AVAILABLE");
				// TODO: Implement Exponential Backoff
			}
			else if(regError.equals(ACCOUNT_MISSING)) {
				System.out.println("C2DMReceiver: ACCOUNT_MISSING");
				// There is no Google account on the phone. 
				// The application should ask the user to open the account manager and add a Google account.
				// Fix on the device side.
			}
			else if(regError.equals(AUTHENTICATION_FAILED)) {
				System.out.println("C2DMReceiver: AUTHENTICATION_FAILED");
				// Bad password. The application should ask the user to enter his/her password, 
				// and let user retry manually later. Fix on the device side.
			}
			else if(regError.equals(TOO_MANY_REGISTRATIONS)) {
				System.out.println("C2DMReceiver: TOO_MANY_REGISTRATIONS");
				// The user has too many applications registered. 
				// The application should tell the user to uninstall some other applications, 
				// let user retry manually. Fix on the device side.
			}
			else if(regError.equals(INVALID_SENDER)) {
				System.out.println("C2DMReceiver: INVALID_SENDER");
				// The sender account is not recognized.
			}
			else if(regError.equals(PHONE_REGISTRATION_ERROR)) {
				System.out.println("C2DMReceiver: PHONE_REGISTRATION_ERROR");
				// Incorrect phone registration with Google. This phone doesn't currently support C2DM
			}
		}
		else if(intent.getStringExtra(UNREGISTERED) != null)
		{
			System.out.println("HandleRegistration: Unregistered");
		}
		else if(registrationId != null)
		{
			
			System.out.println("HandleRegistration: Registration id = " + registrationId);

			Intent i = new Intent(context, com.rit.secs.SECS.class);		
			i.addFlags(Intent.FLAG_FROM_BACKGROUND);
			i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
			i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			i.putExtra("Registration", registrationId);
			i.setAction("REGISTRATION");
			context.startActivity(i);
			
			ServerComm.setRegistrationID(registrationId);
			ServerComm.sendRegistrationIdToSQS();
		}
		else
		{
			System.err.println("HandleRegistration: Unknown registration problem");
		}
	}
	
	private void handleMessage(Context context, Intent intent) {
		System.out.println("received message intent");
		String message = intent.getExtras().getString("message");
		System.out.println("message: " + message);
		
		try {
			Messages.Message msg = Util.GetMessageObject(message);
			if(msg instanceof Messages.EntrantDetected) {
				handleEntrant(context, msg);
			}
			else if(msg instanceof Messages.AlertCanceled) {
				handleCanceled(context, msg);
			}
			else if(msg instanceof Messages.CommandReceived) {
				Toast.makeText(context, "Bluetooth Command Received!", Toast.LENGTH_LONG).show();
			}
		} catch (InvalidVarListException e) {
			e.printStackTrace();
		}
	}
	
	private void handleCanceled(Context context, Messages.Message msg) {
		String reason;
		reason = msg.GetVar(AlertCanceled.REASON);
		System.out.println("Reason = " + reason);
		
		// Change the reason to something more appropriate
		if(reason.equals("grantAccess")) {
			reason = "PC Application used.";
		}
		
		// Check to see if application is running
		boolean activeSECS = SECS.amIActive;
		boolean activePopup = PopupActivity.amIActive;
		boolean activeConfig = Configuration.amIActive;
		
		// If SECS is active, start send the alert
		if(activeSECS || activeConfig) {
			System.out.println("context = " + context.toString());
			Intent intent = new Intent(context, com.rit.secs.SECS.class);
			intent.addFlags(Intent.FLAG_FROM_BACKGROUND);
			intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
			intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			intent.putExtra("Reason", reason);
			intent.setAction("ALERT_CANCELED");
			context.startActivity(intent);
		}
		else if(activePopup){
			Intent i = new Intent(context, com.rit.secs.PopupActivity.class); 
			i.setAction("ALERT_CANCELED");
			i.putExtra("Reason", reason);
			i.addFlags(Intent.FLAG_FROM_BACKGROUND);
			i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
			i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		    context.startActivity(i);
		}
	}
	
	private void handleEntrant(Context context, Messages.Message msg) {
		
		String timestamp, cameraIp, cameraPort, queueName;		
		timestamp = msg.GetVar(EntrantDetected.TIMESTAMP);
		cameraIp = msg.GetVar(EntrantDetected.CAMERA_IP_ADDR);
		cameraPort = msg.GetVar(EntrantDetected.CAMERA_ACCESS_PORT);
		queueName = msg.GetVar(EntrantDetected.QUEUE_NAME);
		System.out.println("timestamp = " + timestamp);
		System.out.println("cameraIp = " + cameraIp);
		System.out.println("cameraPort = " + cameraPort);
		System.out.println("queueName = " + queueName);
		
		// Set the ServerComm variables from the message information
		ServerComm.setCameraIP(cameraIp);
		ServerComm.setCameraPort(cameraPort);
		ServerComm.setQueueName(queueName);
		ServerComm.setQueueName(queueName);
		
		// Check to see if application is running
		boolean active = SECS.amIActive;
		System.out.println("Is SECS currently active? = " + SECS.amIActive);
		
		// If SECS is active, start the camera connection
		if(active) {
			System.out.println("context = " + context.toString());
			Intent intent = new Intent(context, com.rit.secs.SECS.class);
			intent.addFlags(Intent.FLAG_FROM_BACKGROUND);
			intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
			intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			intent.setAction("CAMERA");
			context.startActivity(intent);
		}
		
		// Else open the pop-up activity
		else {
			Intent i = new Intent(context, com.rit.secs.PopupActivity.class); 
			i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		    context.startActivity(i); 
		}
	}
	
	
}
